#include "Common.fxh"

cbuffer cbPerObject
{
	float4x4 gWorldView;
	float3 gDiffColor;
	float2 gSpecIntensAndPower;
};

Texture2D gDiffuseMap;
Texture2D gNormalMap;
Texture2D gSpecularMap;

cbuffer cbPerFrame
{
	float4x4 gProj;
};

struct VS_IN
{
	float3 posL     : POSITION;
	float3 normalL  : NORMAL0;
	float3 tangentL : TANGENT0;
	float2 texCoord : TEXCOORD0;
};

struct VS_OUT
{
	float4 posD         : SV_POSITION;
	float3 normalV      : TEXCOORD0;
	float3 tangentV     : TEXCOORD1;
	float2 texCoord     : TEXCOORD2;
	float3 posV         : TEXCOORD3;
};

VS_OUT VS(VS_IN vIn)
{
	VS_OUT vOut;

	float4 posV = mul(float4(vIn.posL, 1.0f), gWorldView);
	
	vOut.posD = mul(posV, gProj);
	vOut.normalV = mul(float4(vIn.normalL, 0.0f), gWorldView).xyz;
	vOut.tangentV = mul(float4(vIn.tangentL, 0.0f), gWorldView).xyz;
	vOut.texCoord = vIn.texCoord;
	vOut.posV = posV.xyz;
	
	return vOut;
}

struct PS_OUT
{
	float Depth           : SV_Target0;
	float4 Normal         : SV_Target1;
	float4 Diffuse_SpecI  : SV_Target2;
	float2 SpecP          : SV_Target3;
};

PS_OUT PS(VS_OUT pIn)
{
	PS_OUT pOut;

	pIn.normalV = normalize(pIn.normalV);
	pIn.tangentV = normalize(pIn.tangentV);
	float3x3 TBN_V = float3x3(pIn.tangentV, normalize(cross(pIn.normalV, pIn.tangentV)), pIn.normalV);

	float3 sampledNormal = 2 * gNormalMap.Sample(gTriLinearSam, pIn.texCoord).xyz - 1.0f;
	float3 normalV = normalize(mul(sampledNormal, TBN_V));

	pOut.Depth = length(pIn.posV);
	pOut.Normal = float4(pIn.normalV, 1.0f);
	//pOut.Normal = encodeNormal(pIn.normalV);
	//pOut.Diffuse_SpecI = float4(gDiffuseMap.Sample(gTriLinearSam, pIn.texCoord).xyz, gSpecularMap.Sample(gTriLinearSam, pIn.texCoord).x);
	pOut.Diffuse_SpecI = float4(gDiffColor, 0.5f);
	pOut.SpecP = float2(encodeSpecPowerToUNorm(gSpecIntensAndPower.y), pIn.normalV.z);

	return pOut;
}

technique11 tech
{
	pass P0
	{
		SetVertexShader( CompileShader( vs_5_0, VS() ) );
		SetGeometryShader( NULL );
		SetPixelShader( CompileShader( ps_5_0, PS() ) );
		
		SetDepthStencilState(DepthOn, 0);
		SetBlendState( NoBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
		SetRasterizerState(CullBackMS);
	}
}
